# ----------------------------------------------------------------------------
#       Copyright (C) 2013-2014 Huynh Vi Lam  <domovilam@gmail.com>
#
#       This file is part of pimucha.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------



# ----------------------------------------------------------------------------
# Use to receive RF events
# from TellStick Duo interface
# Receiving data / USB FTDI Serial
# Require pylibftdi from https://pypi.python.org/pypi/pylibftdi/
# with Python 2.7.x and 3.x
# ----------------------------------------------------------------------------
# Company Telldus Technologies
# ----------------------------
# - Website: http://www.telldus.com
# - Documentation and source code TellStick Duo is used as base for development of scripts
# ----------------------------------------------------------------------------


import logging,time
from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device
from .ctrlfcts.tsduo1fct import (requestcmd)


logger = logging.getLogger()


class TSDUO(Device):

    def __init__(self,port=None,_id=None):
        USB_VID_LIST.append(0x1781)
        USB_PID_LIST.append(0x0c31)
        self.idcontroller = 'TSDUO'
        self.opened = False
        self.setup = False
        self.TXcap = True
        self.RXcap = True
        try:
            Device.__init__(self,'A6028C22',mode='b',encoding='latin1')
            self.opened = True
        except Exception as e:
            logger.critical("%s : %s", repr(e.__class__), str(e))
            self.port = 'PortUnavailable'
            return

    def tsetup(self):
        """
        Setup interface with request version test
        """
        if not self.opened: return
        logger.debug("Starting %s with version request....",self.idcontroller)
        try:
            self.flush()
        except Exception as e:
            logger.critical("%s : %s", repr(e.__class__), str(e))
            self.port = 'PortUnavailable'
            return
        data = self.request('VERS')
        logger.warning("%s Ready....",self.idcontroller)
        self.setup = True
        self.device = self.idcontroller + '-ftdiport'


    def flush(self):
        logger.debug("Flush interface buffer %s...",self.idcontroller)
        n = 0
        while n < 5:
            n += 1
            res = self.read(100)
            if not res:
                time.sleep(0.1)
        return res

    def request(self,rcmd):
        return requestcmd(self,rcmd)

    def plsend(self):
        return None

    def rfsend(self,data,ack=None,msgq=None):
        self.flush()
        nb = self.write(data)
        logger.debug("Nb caracters write to controller %s",repr(nb))
        time.sleep(1)
        res = self.read(15)
        if not res:
            logger.debug("No response from controller")
            return None
        logger.debug("Result %s...",repr(res))
        if (len(res) > 0) and ack:
            if ack == res[0:2]:
                logger.debug("Success of command : %s",repr(ack))
                return ack
        return res

    def rxevent(self,maxlen=100):
        """
        Read one event after flush/pause
        Cut down data
        and eliminates same events
        """
        LEVT = "+W".encode('latin1')
        REVT = ";\r\n".encode('latin1')
        data = self.read(maxlen)
        if not data :
            return None
        events = []
        n = data.count(LEVT)
        if n == 0 :
            return None
        a = data.split(REVT)[0]            
        first = a[2:]
        events.append(first)
        if n > 1:
            next = self.read(10 * maxlen)
            if next:
                n1 = next.count(LEVT)
                data += next
                n += n1
                evts = data.split(REVT)
                for a in evts[1:-1]:
                    e = a[2:]
                    if e not in events:
                        events.append(e)
                logger.warning("Cut down data into %s fragments with %s different events",str(n),str(len(events)))
        return '|'.join(events)
